package com.sunlands.zlcx.usercenter.controller;

import com.google.common.base.Splitter;
import com.sunlands.zlcx.usercenter.client.LiveVideoService;
import com.sunlands.zlcx.usercenter.client.UserFansService;
import com.sunlands.zlcx.usercenter.client.UserFriendsService;
import com.sunlands.zlcx.usercenter.client.UserDiaryService;
import com.sunlands.zlcx.usercenter.client.bean.TimeLearnRoomVO;
import com.sunlands.zlcx.usercenter.common.annotation.AuthSig;
import com.sunlands.zlcx.usercenter.common.annotation.AutoLog;
import com.sunlands.zlcx.usercenter.config.ClientConfig;
import com.sunlands.zlcx.usercenter.constant.AppEnum;
import com.sunlands.zlcx.usercenter.constant.BlackEnum;
import com.sunlands.zlcx.usercenter.constant.YN;
import com.sunlands.zlcx.usercenter.domain.CityDO;
import com.sunlands.zlcx.usercenter.domain.SchoolDO;
import com.sunlands.zlcx.usercenter.domain.UsersDO;
import com.sunlands.zlcx.usercenter.domain.UsersExtInfoDO;
import com.sunlands.zlcx.usercenter.domain.log.LoginLogDO;
import com.sunlands.zlcx.usercenter.domain.log.UserOnlineLogDO;
import com.sunlands.zlcx.usercenter.exception.CheckRunException;
import com.sunlands.zlcx.usercenter.exception.GlobalExceptionHandler;
import com.sunlands.zlcx.usercenter.exception.UserLoginLimitException;
import com.sunlands.zlcx.usercenter.service.*;
import com.sunlands.zlcx.usercenter.util.BeanPropertiesUtil;
import com.sunlands.zlcx.usercenter.util.ClientUtil;
import com.sunlands.zlcx.usercenter.util.StringUtil;
import com.sunlands.zlcx.usercenter.util.Version;
import com.sunlands.zlcx.usercenter.vo.*;
import com.sunlands.zlcx.usercenter.vo.feign.TzUserBlacklist;
import com.sunlands.zlcx.usercenter.vo.feign.UserRelationVO;
import com.sunlands.zlcx.usercenter.vo.feign.UsersGroupVO;
import com.sunlands.zlcx.usercenter.vo.response.BusinessResult;
import com.sunlands.zlcx.usercenter.vo.response.PageResultVO;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.http.util.Asserts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.Collator;
import java.time.*;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

import static com.sunlands.zlcx.usercenter.common.annotation.AutoLog.Level.DEBUG;
import static com.sunlands.zlcx.usercenter.domain.UsersDO.IdentityEnums.COLLEGE_STUDENT;
import static com.sunlands.zlcx.usercenter.domain.UsersExtInfoDO.PHONE_MODEL;
import static com.sunlands.zlcx.usercenter.domain.UsersExtInfoDO.VERSION;
import static com.sunlands.zlcx.usercenter.vo.CommonResultMessage.MP_LOGIN_CODE_ERROR;

/**
 * @author anjl
 * @date 1:35 PM 2019/4/15
 * description:
 */
@SuppressWarnings("unused")
@Api(tags = "2、用户（道友）信息")
@ApiResponses(value = {@ApiResponse(code = 400, response = GlobalExceptionHandler.class, message = "数据校验失败"), @ApiResponse(code = 500, response = GlobalExceptionHandler.class, message = "内部错误")})
@Slf4j
@Configuration
@RestController
@RequestMapping("/users")
public class UsersController implements AuthSupport, BeanPropertiesUtil {

    private static final String DEFAULT_TARGET_NAME = "考研";
    //用户被禁止登陆状态
    public static final Integer LOGIN_LIMIT_STATUS = -2;
    @Value("${app.appStoreUrl}")
    private String appStoreUrl;
    @Value("${app.appShareUrl}")
    private String appShareUrl;
    private static final String GENERAL_PASSWORD = "FEWFHI382J3BH32H2V1E2#@#@@F*(V#B#H&J$N$%^#TBT#W%RV@$$RCRVGR";
    private static final String DEFAULT_AVATAR_URL = "https://tximg.sunlands.wang/tongzhuo/avatar/default2.png";

    @AutoLog
    @ApiOperation(value = "为兼容，暂时预留", notes = "手机注册用户")
    @PostMapping
    @AuthSig
    public BusinessResult<AccessTokenVO> addUsers(HttpServletRequest request, @RequestBody RegisterVO registerVO) {

        //检查数据格式
        String message = checkRegister(registerVO);
        if (null != message) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE.code, message);
        }
        //检查验证码
        CommonResultMessage verifyResult = verifyPhoneVerifyCode(registerVO.getPhone(), registerVO.getCode());
        if (Objects.nonNull(verifyResult)) {
            return BusinessResult.createInstance(CommonResultMessage.VERIFY_CODE_ERROR.code, verifyResult.message);
        }
        UsersVO usersVO = usersService.findByPhone(registerVO.getPhone());

        if (Objects.isNull(usersVO)) {
            //注册
            UsersDO usersDO = UsersDO
                    .builder()
                    .phone(registerVO.getPhone())
                    .type(UsersDO.TypeEnums.INCOMPLETE.code)
                    .avatarUrl(DEFAULT_AVATAR_URL)
                    .build();
            usersVO = usersService.save(usersDO);
        }

        if (Objects.nonNull(usersVO) && LOGIN_LIMIT_STATUS.equals(usersVO.getStatus())) {
            throw new UserLoginLimitException();
        }
        //发起登录
        AccessTokenVO token = userDetailsService.getPasswordToken(usersVO.getUsername(), GENERAL_PASSWORD);

        //登录成功后刷新token，使之前的token失效，防止多处登录
        token = userDetailsService.refreshToken(token.getRefreshToken());
        String app = getApp(request);
        updateLoginState(app, usersVO);
        loginLog(usersVO.getId(), usersVO.getName(), ClientUtil.getIpAddr(request), LoginLogDO.LoginTypeEnum.PHONE_LOGIN.type);

        log.info("手机验证码登录成功！usersVO = {}", usersVO);
        return BusinessResult.createSuccessInstance(token);

    }

    @AutoLog
    @ApiOperation(value = "手机注册登录", notes = "手机注册用户")
    @PostMapping("/code-login")
    @AuthSig
    public BusinessResult<AccessTokenVO> codeLogin(HttpServletRequest request, @RequestBody RegisterVO registerVO) {

        //检查数据格式
        String message = checkRegister(registerVO);
        if (null != message) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE.code, message);
        }

        //检查验证码
        CommonResultMessage verifyResult = verifyPhoneVerifyCode(registerVO.getPhone(), registerVO.getCode());
        if (Objects.nonNull(verifyResult)) {
            return BusinessResult.createInstance(CommonResultMessage.VERIFY_CODE_ERROR.code, verifyResult.message);
        }
        UsersVO usersVO = usersService.findByPhone(registerVO.getPhone());
        if (Objects.isNull(usersVO)) {
            //注册
            UsersDO usersDO = UsersDO.builder().phone(registerVO.getPhone()).type(UsersDO.TypeEnums.INCOMPLETE.code).avatarUrl(DEFAULT_AVATAR_URL).build();
            usersVO = usersService.save(usersDO);
        }

        if (Objects.nonNull(usersVO) && LOGIN_LIMIT_STATUS.equals(usersVO.getStatus())) {
            throw new UserLoginLimitException();
        }

        //发起登录
        AccessTokenVO token = userDetailsService.getPasswordToken(usersVO.getUsername(), GENERAL_PASSWORD);
        //登录成功后刷新token，使之前的token失效，防止多处登录
        token = userDetailsService.refreshToken(token.getRefreshToken());
        String app = getApp(request);
        updateLoginState(app, usersVO);
        loginLog(usersVO.getId(), usersVO.getName(), ClientUtil.getIpAddr(request), LoginLogDO.LoginTypeEnum.PHONE_LOGIN.type);
        log.info("手机验证码登录成功！usersVO = {}", usersVO);

        return BusinessResult.createSuccessInstance(token);
    }

    private void addTarget(Long userId) {
        UsersTargetRelationVO target = UsersTargetRelationVO
                .builder()
                .targetName(DEFAULT_TARGET_NAME)
                .targetId(14L)
                .status(YN.YES.getCode())
                .studyHours(BigDecimal.ZERO)
                .userId(userId)
                .userName("-")
                .build();
        try {
            targetService.addUserTarget(target);
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }


    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "（内部）查询用户信息", notes = "查询用户信息")
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/{id}")
    @AuthSig
    public BusinessResult<UsersVO> find(HttpServletRequest request, @ApiParam(value = "用户id") @PathVariable Long id) {
        UsersVO usersVO = usersService.find(id);
        if (null == usersVO) {
            log.info("查询用户信息 id={},usersVO={}", id, usersVO);
            return BusinessResult.createSuccessInstance(null);
        }
        return BusinessResult.createSuccessInstance(usersVO);
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "（内部）查询用户信息，返回用户实时学习状态状态（不需要请调用另一个查询用户信息的方法）", notes = "查询用户信息", position = 30)
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/find-one/{id}")
    @AuthSig
    public BusinessResult<UsersVO> findOne(HttpServletRequest request, @ApiParam(value = "用户id") @PathVariable Long id) {
        UsersVO usersVO = usersService.findOne(id);
        if (Objects.isNull(usersVO)) {
            log.info("查询用户信息 id = {},usersVO = null", id);
        }
        return BusinessResult.createSuccessInstance(usersVO);
    }


    @AutoLog
    @ApiOperation(value = "个人主页", notes = "个人主页")
    @GetMapping("/user-homepage/{id}")
    @AuthSig
    public BusinessResult<UsersVO> findHomePage(HttpServletRequest request, @ApiParam(value = "用户id") @PathVariable Long id) {
        Long userId = currentUserId();
        UsersVO usersVO = id.equals(userId) ? usersService.findOne(id) : usersService.find(id);

        if (Objects.nonNull(usersVO)) {

            perfectRelation(currentUserId(), usersVO);
            perfectFriendCount(id, usersVO);
            perfectStudyHoursAndDiaryCount(usersVO);

            Long currUserId = currentUserId();
            if (Objects.nonNull(currUserId) && !currUserId.equals(id)) {
                //判断是否加入黑名单
                List<TzUserBlacklist> result = tzUserFriendsService.checkBlack(currUserId, id).getData();
                if (!CollectionUtils.isEmpty(result)) {
                    usersVO.setBlackStatus(BlackEnum.passive.code);
                    usersVO.setIsFriend(0);
                    Map<Long, List<TzUserBlacklist>> listMap = result.stream().collect(Collectors.groupingBy(TzUserBlacklist::getOprationUserId));
                    if (listMap.containsKey(currUserId)) {
                        usersVO.setBlackStatus(BlackEnum.active.code);
                    }
                }

            }

            if (UsersDO.StatusEnums.LEARN_TIME_ROOM_LEARNING.code.equals(usersVO.getStatus()) && Objects.nonNull(usersVO.getRoomId())) {
                TimeLearnRoomVO room = liveVideoService.getSimpleRoomInfo(usersVO.getRoomId()).getData();
                usersVO.setRoomType(Objects.nonNull(room) ? room.getType() : null);
            }

            return BusinessResult.createSuccessInstance(usersVO);
        }
        return BusinessResult.createInstance(CommonResultMessage.INVALID_USER);
    }

    private void perfectStudyHoursAndDiaryCount(UsersVO usersVO) {

        UsersTargetRelationVO usersTargetRelation = targetService.getUserTarget(usersVO.getId());
        if (Objects.nonNull(usersTargetRelation)) {
            usersVO.setStudyHours(targetService.getStudyHours(usersVO.getId()));

            //设置目标创建天数
            Instant instant = usersTargetRelation.getCreateTime().toInstant();
            LocalDate targetCreateDay = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalDate();
            usersVO.setTargetDays(Period.between(targetCreateDay, LocalDate.now()).getDays());
        } else {
            usersVO.setStudyHours(BigDecimal.ZERO);
            usersVO.setTargetDays(0);
        }
        //查询用户发布日记数量
        usersVO.setDiaryCount(userDiaryService.countByUserId(usersVO.getId()).getData());
        usersVO.setStudyCount(usersStudyService.countLearnByUserId(usersVO.getId()));
    }

    @AutoLog
    @ApiOperation(value = "自己个人主页", notes = "自己个人主页")
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/user-homepage/self")
    @AuthSig
    public BusinessResult<UsersVO> findSelfHomePage(HttpServletRequest request) {
        Long id = currentUserId();
        try {
            handleUserExtInfo(request, id);
            log.info("自己个人主页 request={}", request.getParameterMap());
        } catch (Exception e) {
            log.error("user ext info handle error id ={}, request={}", id, request.getParameterMap());
            log.error("", e);
        }
        log.debug("个人主页 id = {}", id);
        return findHomePage(request, id);
    }

    /**
     * 处理用户扩展信息
     *
     * @param request
     * @param id
     */
    @Async
    void handleUserExtInfo(HttpServletRequest request, Long id) {
        UsersExtInfoDO extInfo = UsersExtInfoDO.builder().userId(id).operatingSystem(ClientUtil.getOs(request)).phoneModel(request.getHeader(PHONE_MODEL)).version(request.getHeader(VERSION)).build();
        UsersExtInfoDO existExtInfo = usersService.findExtInfoByUserId(id);
        if (Objects.isNull(existExtInfo) ||
                (Objects.isNull(existExtInfo.getOperatingSystem()) && Objects.nonNull(extInfo.getOperatingSystem())) ||
                !existExtInfo.getOperatingSystem().equals(extInfo.getOperatingSystem()) ||
                (Objects.isNull(existExtInfo.getPhoneModel()) && Objects.nonNull(extInfo.getPhoneModel())) ||
                (StringUtils.isNotBlank(extInfo.getPhoneModel()) && !existExtInfo.getPhoneModel().equals(extInfo.getPhoneModel())) ||
                (Objects.isNull(existExtInfo.getPhoneModel()) && Objects.nonNull(extInfo.getPhoneModel())) ||
                (StringUtils.isNotBlank(extInfo.getVersion()) && !existExtInfo.getVersion().equals(extInfo.getVersion()))) {
            usersService.saveExtInfo(extInfo);
        }
        usersService.learnTimingHandler(id);
    }

    /**
     * 完善粉丝数和关注数
     *
     * @param id      id
     * @param usersVO usersVO
     * @return UsersVO
     */
    private UsersVO perfectFriendCount(Long id, UsersVO usersVO) {
        FriendFollowVO friendFollow = tzUserFriendsService.friendsFollowNumbers(id).getData();
        usersVO.setFansCount(friendFollow.getFansNumbers());
        usersVO.setFollowCount(friendFollow.getFollowsNumbers());
        usersVO.setFriendCount(friendFollow.getFriendsNumbers());
        return usersVO;
    }

    /**
     * 完善用户关系
     *
     * @param currentUserId currentUserId
     * @param usersVO       usersVO
     * @return UsersVO
     */
    private UsersVO perfectRelation(Long currentUserId, UsersVO usersVO) {

        if (Objects.isNull(currentUserId)) {
            usersVO.setIsFans(0);
            usersVO.setIsFriend(0);
            return usersVO;
        }

        if (currentUserId.equals(usersVO.getId())) {
            //-1代表自己
            usersVO.setIsFriend(-1);
            usersVO.setIsFans(-1);
        } else {
            UserRelationVO relation = tzUserFansService.relation(currentUserId, usersVO.getId()).getData();
            //如果是道友
            if (relation.getFriendStatus().equals(1)) {
                usersVO.setIsFriend(1);
            } else {
                if (relation.getSendFriendState().equals(1) || relation.getSendFriendState().equals(4)) {
                    usersVO.setIsFriend(2);
                } else {
                    usersVO.setIsFriend(0);
                }
            }

            if (relation.getFansStatus().equals(1) || relation.getFansStatus().equals(3)) {
                //a是b的粉丝
                usersVO.setIsFans(1);
            } else {
                usersVO.setIsFans(0);
            }

        }
        return usersVO;
    }

    /**
     * 判断用户道友关系
     *
     * @param usersVO  usersVO
     * @param relation relation
     */
    private void setIsFriend(UsersVO usersVO, UserRelationVO relation) {
        //a对b发送好友请求
        if (relation.getSendFriendState().equals(1) || relation.getSendFriendState().equals(4)) {
            usersVO.setIsFriend(2);
            //a对b为发送好友请求
        } else {
            usersVO.setIsFriend(0);
        }
    }


    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "（内部）查询虚拟用户", notes = "查询虚拟用户")
    @PreAuthorize("isAuthenticated()")
    @GetMapping
    @AuthSig
    public BusinessResult<List<UsersVO>> search(HttpServletRequest request, @ApiParam(value = "用户昵称") @RequestParam(required = false) String name, @ApiParam(value = "手机号") @RequestParam(required = false) String phone, @ApiParam(value = "用户类型 1是真实用户 -1是虚拟用户") @RequestParam(required = false) Integer type) {
        List<UsersVO> list = new ArrayList<>();
        if (StringUtils.isNotBlank(name)) {
            list = usersService.findByName(name);
        }
        if (StringUtils.isNotBlank(phone)) {
            UsersVO usersVO = usersService.findByPhone(phone);
            if (!usersVO.getType().equals(UsersDO.TypeEnums.INCOMPLETE.code)) {
                list = Collections.singletonList(usersVO);
            }
        }
        if (Objects.nonNull(type)) {
            list = usersService.findByType(type);
        }
        return BusinessResult.createSuccessInstance(list);
    }

    @AutoLog
    @ApiOperation(value = "获取公众号签名信息", notes = "获取公众号签名信息")
    @GetMapping("/jsapi/ticket")
    @AuthSig
    public BusinessResult<String> ticket() throws WxErrorException {
        String jsapiTicket = wxMpService.getJsapiTicket();
        return BusinessResult.createSuccessInstance(jsapiTicket);
    }


    @AutoLog
    @ApiOperation(value = "用户搜索", notes = "用户搜索")
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/search")
    @AuthSig
    public BusinessResult<List<UsersVO>> search(HttpServletRequest request, @ApiParam(value = "用户昵称") @RequestParam(required = false) String name, @ApiParam(value = "手机号") @RequestParam(required = false) String phone) {
        UsersDO usersDO = currentUsers(usersService);
        List<UsersVO> list = new ArrayList<>();
        if (StringUtils.isNotBlank(name)) {
            list = usersService.findByName(name);
        }
        if (StringUtils.isNotBlank(phone)) {
            list = Collections.singletonList(usersService.findByPhone(phone));
        }

        if (!list.isEmpty()) {
            list = list.stream().filter(users -> !usersDO.getId().equals(users.getId())).map(user -> perfectRelation(usersDO.getId(), user)).collect(Collectors.toList());
        }
        return BusinessResult.createSuccessInstance(list);
    }

    @AutoLog
    @ApiOperation(value = "用户昵称模糊搜索", notes = "用户昵称模糊搜索")
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/vague/search")
    @AuthSig
    public BusinessResult<PageResultVO<UsersVO>> vagueSearch(HttpServletRequest request, @ApiParam(value = "用户昵称") @RequestParam(required = true) String name,
                                                             @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
                                                             @ApiParam(value = "页码大小") @RequestParam(defaultValue = "40") Integer pageSize) {
        Map map = new HashMap();

        if (StringUtils.isEmpty(name)) {
            return BusinessResult.createSuccessInstance(new PageResultVO(0, Collections.EMPTY_LIST));
        }
        page--;
        UsersDO usersDO = currentUsers(usersService);
        PageRequest pageable = new PageRequest(page, pageSize);
        PageResultVO<UsersVO> usersVOPageResultVO = usersService.findByNameLike(name, usersDO.getId(), pageable);
        List<Long> friendsUserId = new ArrayList<>();
        usersVOPageResultVO.getRows().forEach(usersVO -> friendsUserId.add(usersVO.getId()));
        log.info("usersDO.getId() : {}, friendsUserId : {}", usersDO.getId(), friendsUserId);
        if (!CollectionUtils.isEmpty(friendsUserId)) {
            BusinessResult<List<UserRelationVO>> relationList = tzUserFansService.relationList(usersDO.getId(), friendsUserId);
            List<TzUserBlacklist> myBlacklist = tzUserFriendsService.myBlacklist(usersDO.getId()).getData();
            Set<Long> longSet = new HashSet<>();
            if (!CollectionUtils.isEmpty(myBlacklist)) {
                longSet = myBlacklist.stream().map(tzUserBlacklist -> tzUserBlacklist.getFriendsUserId()).collect(Collectors.toSet());
            }

            Map<Long, List<UserRelationVO>> listMap = relationList.getData().stream().collect(Collectors.groupingBy(o -> o.getOtherUserId()));
            Set<Long> finalLongSet = longSet;
            usersVOPageResultVO.getRows().forEach(usersVO -> {
                UserRelationVO relation = listMap.get(usersVO.getId()).get(0);
                //如果是道友
                if (relation.getFriendStatus().equals(UserRelationVO.FriendEnums.friend.code)) {
                    usersVO.setIsFriend(UserRelationVO.FriendEnums.friend.code);
                } else {
                    if (relation.getSendFriendState().equals(UserRelationVO.SendFriendStateEnums.userToOther.code) ||
                            relation.getSendFriendState().equals(UserRelationVO.SendFriendStateEnums.each.code)) {
                        usersVO.setIsFriend(UserRelationVO.FriendEnums.sendAndNoFriend.code);
                    } else {
                        usersVO.setIsFriend(UserRelationVO.FriendEnums.nothing.code);
                    }
                }

                if (relation.getFansStatus().equals(UserRelationVO.FansEnums.userToOther.code) || relation.getFansStatus().equals(UserRelationVO.FansEnums.each.code)) {
                    //a是b的粉丝
                    usersVO.setIsFans(UserRelationVO.FansEnums.userToOther.code);
                } else {
                    usersVO.setIsFans(UserRelationVO.FansEnums.nothing.code);
                }

                if (finalLongSet.contains(usersVO.getId())) {
                    usersVO.setIsFriend(UserRelationVO.FriendEnums.nothing.code);
                    usersVO.setIsFans(UserRelationVO.FansEnums.nothing.code);
                }
            });
        }

        return BusinessResult.createSuccessInstance(usersVOPageResultVO);
    }


    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "根据idList查询", notes = "根据idList查询")
    @PreAuthorize("isAuthenticated()")
    @PostMapping("/list")
    @AuthSig
    public BusinessResult<List<UsersVO>> findByIdIn(HttpServletRequest request, @ApiParam(value = "用户id集合") @RequestBody List<Long> idList) {
        if (idList.isEmpty()) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
        }
        List<UsersVO> usersList;
        if (idList.size() == 4) {
            log.debug("user list cache ");
            usersList = usersService.findByIdIn(idList);
        } else if (idList.size() < 4) {
            usersList = idList.stream().map(id -> usersService.find(id)).collect(Collectors.toList());
        } else {
            usersList = usersService.findByIdIn(idList);
        }
        return BusinessResult.createSuccessInstance(usersList);
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "根据idList查询(内部用-无缓存)", notes = "根据idList查询（无缓存）")
    @PreAuthorize("isAuthenticated()")
    @PostMapping("/list/newest")
    @AuthSig
    public BusinessResult<List<UsersVO>> list(HttpServletRequest request, @ApiParam(value = "用户id集合") @RequestBody List<Long> idList) {
        if (idList.isEmpty()) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
        }
        return BusinessResult.createSuccessInstance(usersService.find(idList));
    }


    @AutoLog
    @Deprecated
    @ApiOperation(value = "用户手机是否注册", notes = "用户手机是否注册")
    @GetMapping("/phone/exist")
    @AuthSig
    public BusinessResult<Boolean> phoneExist(@ApiParam(required = true, value = "手机号码") @RequestParam String phone) {
        try {
            if (StringUtil.isEmpty(phone)) {
                return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
            }
            boolean exist = Objects.nonNull(usersService.findByPhone(phone));
            if (exist) {
                return BusinessResult.createInstance(CommonResultMessage.PHONE_EXIST);
            }
            return BusinessResult.createSuccessInstance(exist);
        } catch (Exception ex) {
            log.error("", ex);
        }
        return BusinessResult.createInstance(CommonResultMessage.UNKOWN_ERROR);
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "查询与当前用户关系", notes = "查询与当前用户关系", position = 61)
    @GetMapping("/relation/{id}")
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    public BusinessResult<UsersVO> relation(@PathVariable Long id) {
        UsersVO usersVO = UsersVO.builder().id(id).build();
        return BusinessResult.createSuccessInstance(perfectRelation(currentUserId(), usersVO));
    }

    @AutoLog
    @Deprecated
    @ApiOperation(value = "手机密码登录", notes = "用户密码登录")
    @PostMapping("/login")
    @AuthSig
    public BusinessResult<AccessTokenVO> login(HttpServletRequest request, @ApiParam(value = "登录信息") @RequestBody LoginVO loginVO) {
        if (StringUtil.isEmpty(loginVO.getPhone()) || StringUtil.isEmpty(loginVO.getPassword())) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
        }
        UsersVO usersVO = usersService.findByPhone(loginVO.getPhone());

        if (Objects.isNull(usersVO)) {
            return BusinessResult.createInstance(CommonResultMessage.INVALID_USER);
        }

        if (LOGIN_LIMIT_STATUS.equals(usersVO.getStatus())) {
            throw new UserLoginLimitException();
        }

        AccessTokenVO token = userDetailsService.getPasswordToken(usersVO.getUsername(), loginVO.getPassword());
        String app = getApp(request);
        updateLoginState(app, usersVO);
        loginLog(usersVO.getId(), usersVO.getName(), ClientUtil.getIpAddr(request), LoginLogDO.LoginTypeEnum.NORMAL_LOGIN.type);

        log.info("手机密码登录成功！usersVO = {}", usersVO);
        return BusinessResult.createSuccessInstance(token);
    }

    @AutoLog
    @ApiOperation(value = "微信登录", notes = "微信登录")
    @PostMapping("/mp-login")
    @AuthSig
    public BusinessResult<AccessTokenVO> mpLogin(HttpServletRequest request, @RequestBody MpLoginVO mpLoginVO) {
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken;
        WxMpUser wxAppUser;
        String app = getApp(request);
        if (StringUtil.isEmpty(mpLoginVO.getCode())) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
        }

        try {
            //获取微信token
            wxMpOAuth2AccessToken = app.equals(AppEnum.tongzhuo.name()) ?
                    wxAppService.oauth2getAccessToken(mpLoginVO.getCode()) :
                    wxAppPostgraduateService.oauth2getAccessToken(mpLoginVO.getCode());

            log.debug("login get mp token = {}", wxMpOAuth2AccessToken);
            wxAppUser = wxAppService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
            log.debug("login get wxMpUser = {}", wxAppUser);

            //系统登录
            AccessTokenVO token = sysLogin(request, wxMpOAuth2AccessToken, wxAppUser);
            return BusinessResult.createSuccessInstance(token);
        } catch (WxErrorException e) {
            log.error("get mp token failure!  WxErrorException", e);
            return BusinessResult.createInstance(MP_LOGIN_CODE_ERROR);
        }
    }

    @AutoLog
    @ApiOperation(value = "退出", notes = "退出")
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/logout")
    @AuthSig
    public BusinessResult logout() {
        UsersDO usersDO = currentUsers(usersService);
        //因为有缓存，需要再查一次库
        UsersVO usersVO = usersService.findOne(usersDO.getId());
        copyNonNullProperties(usersVO, usersDO);
        usersDO.setLoggedIn(UsersDO.LoggedInEnums.NO.code);
        usersService.update(usersDO);
        return BusinessResult.createSuccessInstance(null);
    }

    private String getSign() {
        return org.apache.commons.lang3.StringUtils.reverse(DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.format(new Date()));
    }

    /**
     * 系统登录
     *
     * @param wxMpOAuth2AccessToken 微信token
     * @param wxAppUser             微信用户信息
     * @return AccessTokenVO
     */
    private AccessTokenVO sysLogin(HttpServletRequest request, WxMpOAuth2AccessToken wxMpOAuth2AccessToken, WxMpUser wxAppUser) {
        String app = getApp(request);
        UsersVO usersVO = usersService.findByUnionId(wxMpOAuth2AccessToken.getUnionId());
        //用户不存在时，先进行注册
        if (Objects.isNull(usersVO)) {
            UsersDO usersDO = UsersDO.builder().unionId(wxAppUser.getUnionId()).name(wxAppUser.getNickname()).avatarUrl(StringUtils.isBlank(wxAppUser.getHeadImgUrl()) ? DEFAULT_AVATAR_URL : wxAppUser.getHeadImgUrl()).appOpenId(wxAppUser.getOpenId()).type(UsersDO.TypeEnums.INCOMPLETE.code).build();
            usersVO = usersService.saveNonExistAddFriend(usersDO, null);
        }

        if (Objects.nonNull(usersVO) && LOGIN_LIMIT_STATUS.equals(usersVO.getStatus())) {
            throw new UserLoginLimitException();
        }

        AccessTokenVO token = userDetailsService.getPasswordToken(usersVO.getUsername(), GENERAL_PASSWORD);
        //登录成功后刷新token，使之前的token失效，防止多处登录
        token = userDetailsService.refreshToken(token.getRefreshToken());

        //设备更换时，更新设备id 以及修改登录状态(针对微信邀请用户和更换手机用户)

        usersVO = updateLoginState(app, usersVO);
        loginLog(usersVO.getId(), usersVO.getName(), ClientUtil.getIpAddr(request), LoginLogDO.LoginTypeEnum.MP_LOGIN.type);

        log.info("微信登录成功！usersVO = {}", usersVO);
        return token;
    }

    /**
     * @param code  微信临时授权码
     * @param state 如果不为空 则需要按照   邀请人,道友类型
     */

    @AutoLog
    @ApiOperation(value = "微信用户邀请", notes = "用户邀请")
    @GetMapping("/invite")
    @AuthSig
    public void invite(@RequestParam String code, @RequestParam String state, HttpServletResponse response) throws WxErrorException, IOException {
        authRegisterAddFriend(code, state);
        log.info("invite user success！ code = {} state = {} appStoreUrl = {} ", code, state, appStoreUrl);
        response.sendRedirect(appStoreUrl);
    }

    @AutoLog
    @ApiOperation(value = "下载地址", notes = "下载地址")
    @GetMapping("/download")
    public void downLoad(HttpServletResponse response) throws IOException {
        response.sendRedirect(appStoreUrl);
    }

    @AutoLog
    @ApiOperation(value = "微信用户分享授权", notes = "用户分享授权")
    @GetMapping("/share")
    @AuthSig
    public void share(@RequestParam String code, @RequestParam String state, HttpServletResponse response) throws WxErrorException, IOException {
        UsersVO usersVO = authRegister(code, state);

        log.info("share user success！ code = {} state = {} appStoreUrl = {} ", code, state, appShareUrl + usersVO.getId() + "&learnId=" + state);
        response.sendRedirect(appShareUrl + usersVO.getId() + "&learnId=" + state);
    }

    private UsersVO authRegister(@RequestParam String code, @RequestParam String state) throws WxErrorException {
        UsersDO usersDO = auth(code);
        return usersService.saveNotExist(usersDO);
    }

    private void authRegisterAddFriend(@RequestParam String code, @RequestParam String state) throws WxErrorException {
        UsersDO usersDO = auth(code);
        UsersVO usersVO = usersService.saveNonExistAddFriend(usersDO, state);
    }

    private UsersDO auth(@RequestParam String code) throws WxErrorException {
//        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
//        log.debug("get mp token = {}", wxMpOAuth2AccessToken);
//        WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
        //注册
//        log.debug("获取微信信息 wxMpUser = {}", wxMpUser);
        return UsersDO.builder().unionId(code).avatarUrl("").name("哈哈哈").build();
    }

    private UsersVO updateLoginState(String app, UsersVO usersVO) {
        UsersDO usersDO = UsersDO.builder()
                .id(usersVO.getId())
                .username(usersVO.getUsername())
                .app(app)
                .loggedIn(UsersDO.LoggedInEnums.YES.code)
                .build();


        return UsersVO.from(usersService.update(usersDO));
    }

    private LoginLogDO loginLog(Long userId, String userName, String ip, Integer loginType) {
        usersService.saveUserActiveLog(userId, "-");
        LoginLogDO loginLogDO = LoginLogDO.builder().ip(ip)
                .loginType(loginType)
                .userId(userId)
                .userName(userName)
                .build();
        //检查用户连麦状态，如果正在连麦中进行重置
        gyfTaskExecutor.execute(() -> liveVideoService.checkUserStatus(userId));
        return logService.save(loginLogDO);
    }

    @AutoLog
    @ApiOperation(value = "城市列表", notes = "城市列表")
//    @PreAuthorize("isAuthenticated()")
    @GetMapping("/city-list")
    public BusinessResult<List<CityDO>> cityList() {
        return BusinessResult.createSuccessInstance(usersService.cityList());
    }

    @AutoLog
    @ApiOperation(value = "学校列表", notes = "学校列表")
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/school-list")
    public BusinessResult<List<String>> schoolList() {
        List<SchoolDO> schoolDOS = usersService.schoolList();

        List<String> schoolList = schoolDOS.stream().map(schoolDO -> schoolDO.getSchoolName()).collect(Collectors.toList());
        Comparator<Object> com = Collator.getInstance(java.util.Locale.CHINA);
        Collections.sort(schoolList, com);
        return BusinessResult.createSuccessInstance(schoolList);
    }

    @AutoLog
    @ApiOperation(value = "学校列表---分页", notes = "学校列表---分页")
    @PreAuthorize("isAuthenticated()")
    @GetMapping("/school-page")
    public BusinessResult<PageResultVO<String>> schoolPage(@ApiParam(value = "学校名称") @RequestParam(required = false) String schoolName,
                                                           @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
                                                           @ApiParam(value = "页码大小") @RequestParam(defaultValue = "50") Integer pageSize) {
        page--;
        PageRequest pageable = new PageRequest(page, pageSize);
        PageResultVO<String> schoolPageResultVO = usersService.findBySchoolNameLike(schoolName, pageable);

        return BusinessResult.createSuccessInstance(schoolPageResultVO);
    }

    @AutoLog
    @ApiOperation(value = "更新用户信息", notes = "更新用户信息")
    @PreAuthorize("isAuthenticated()")
    @PutMapping("/{id}")
    @AuthSig
    public BusinessResult<UsersVO> update(HttpServletRequest request, @ApiParam(value = "用户id") @PathVariable Long id, @RequestBody UsersEditVO editVO) {

        if (!id.equals(currentUserId())) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE.code, "只能更新个人信息！");
        }
        String message = checkUpdateUsers(editVO);
        if (null != message) {
            return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE.code, message);
        }

        editVO.setId(id);
        UsersDO usersDO = new UsersDO();
        usersDO.setType(UsersDO.TypeEnums.NORMAL.code);
        copyNonNullProperties(editVO, usersDO);
        UsersVO usersVO = UsersVO.from(usersService.update(usersDO));
        assert usersVO != null;

        String app = getApp(request);
        if (Objects.nonNull(editVO.getSex())) {
            if (app.equals(AppEnum.postgraduate.name()) && Objects.isNull(usersVO.getCurrentLearnTargetId())) {
                addTarget(usersVO.getId());
            }
            if (app.equals(AppEnum.postgraduate.name()) && Objects.isNull(usersVO.getIdentity())) {
                usersDO = UsersDO.builder().id(usersVO.getId()).identity(COLLEGE_STUDENT.type).build();
                usersService.update(usersDO);
            }
        }
        return BusinessResult.createSuccessInstance(usersVO);
    }


    @AutoLog
    @ApiOperation(value = "更改设备id", notes = "更改设备id")
    @PutMapping("/device-id/{deviceId}")
    @AuthSig
    public BusinessResult<UsersVO> updateDeviceId(HttpServletRequest request, @ApiParam(value = "1 开启 0关闭") @PathVariable String deviceId) {
        UsersDO usersDO = currentUsers(usersService);
        if (Objects.nonNull(usersDO) && !deviceId.equals(usersDO.getDeviceId())) {
            usersDO = UsersDO.builder().id(usersDO.getId()).deviceId(deviceId).build();
            return BusinessResult.createSuccessInstance(UsersVO.from(usersService.update(usersDO)));
        }
        UsersVO usersVO = UsersVO.from(usersDO);
        return BusinessResult.createSuccessInstance(usersVO);
    }

    @AutoLog
    @ApiOperation(value = "开启/关闭免打扰", notes = "开启/关闭免打扰")
    @PreAuthorize("isAuthenticated()")
    @PutMapping("/disturb")
    @AuthSig
    public BusinessResult<UsersVO> updateDisturb(HttpServletRequest request, @RequestParam Integer disturb) {
        if (disturb != 1 && disturb != 0) {
            throw new IllegalArgumentException("disturb 参数不合法!");
        }
        UsersDO usersDO = currentUsers(usersService);
        usersDO.setDisturb(disturb);
        UsersVO usersVO = UsersVO.from(usersService.update(usersDO));
        return BusinessResult.createSuccessInstance(usersVO);
    }

    @AutoLog
    @ApiOperation(value = "发送短信通知，reprtContent为空时发生短信验证码", notes = "发送短信通知,reprtContent为空时发生短信验证码")
    @GetMapping("/send/verify/code")
    @AuthSig
    public BusinessResult<Void> sendPhoneVerifyCode(HttpServletRequest request,
                                                    @ApiParam(value = "手机号码,多个手机号码，逗号隔开") @RequestParam String phoneStr,
                                                    @ApiParam(value = "通知内容") @RequestParam(required = false) String reportContent,
                                                    @ApiParam(value = "补充机制--腾讯云短信参数") @RequestParam(required = false) ArrayList<String> params) {
        try {
            if (StringUtil.isEmpty(phoneStr)) {
                return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
            }
            String app = getApp(request);
            List<String> phoneList = Splitter.on(",").omitEmptyStrings().splitToList(phoneStr).stream().collect(Collectors.toList());
            for (String phone : phoneList) {
                boolean success = usersService.sendSMSWithKong(app, phone, reportContent, params);
                if (!success) {
                    log.error("sendPhoneVerifyCode  error ={}", CommonResultMessage.VERIFY_CODE_SEND_ERROR.getMessage() + phone);
                }
            }
            return BusinessResult.createSuccessInstance(null);
        } catch (CheckRunException ex) {
            log.error("", ex);
            return BusinessResult.createInstance(CommonResultMessage.VERIFY_CODE_SEND_FREQUENCY);
        }
    }


    @AutoLog
    @ApiOperation(value = "验证绑定手机号", notes = "验证绑定手机号 11006、手机号已经注册 11026、手机号码已经绑定到该用户")
    @PostMapping("/binding/phone")
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    public BusinessResult<AccessTokenVO> bindingPhone(@RequestBody BingingPhoneVO bingingPhone) {

        Asserts.notNull(bingingPhone.getPhone(), "手机号不能为空！");
        Asserts.notNull(bingingPhone.getCode(), "验证码不能为空！");
        //检查验证码
        CommonResultMessage verifyResult = verifyPhoneVerifyCode(bingingPhone.getPhone(), bingingPhone.getCode());

        if (Objects.nonNull(verifyResult)) {
            return BusinessResult.createInstance(CommonResultMessage.VERIFY_CODE_ERROR.code, verifyResult.message);
        }
        UsersVO phoneUser = usersService.findByPhone(bingingPhone.getPhone());

        Long userId = currentUserId();
        UsersVO one = usersService.findOne(userId);
        UsersDO result;
        //曾经绑定过手机号
        if (YN.YES.getCode() == one.getBingingPhone()) {
            if (Objects.isNull(phoneUser)) {
                UsersDO usersDO = UsersDO
                        .builder()
                        .id(userId)
                        .phone(bingingPhone.getPhone())
                        .build();
                result = usersService.update(usersDO);
                log.info("用户更换手机号 user = {} 新手机号(未关联任何用户) = {}", one, bingingPhone.getPhone());
            } else {
                if (Objects.nonNull(one.getPhone()) && one.getPhone().equals(phoneUser.getPhone())) {
                    log.debug("该手机号已经绑定到此用户身上，请更换手机号重新绑定 user = {} 新手机号 = {}", one, bingingPhone.getPhone());
                    return BusinessResult.createInstance(CommonResultMessage.PHONE_HAS_BINDING_TO_THIS_USER);
                } else {
                    log.debug("该手机号已经绑定到其他用户身上，请更换手机号重新绑定 user = {} 新手机号 = {}", one, bingingPhone.getPhone());
                    return BusinessResult.createInstance(CommonResultMessage.PHONE_EXIST);
                }
            }
        } else {
            if (Objects.isNull(phoneUser)) {
                UsersDO usersDO = UsersDO
                        .builder()
                        .id(userId)
                        .phone(bingingPhone.getPhone())
                        .build();
                result = usersService.update(usersDO);
                log.info("用户第一次绑定手机号 user = {} 新手机号(未关联任何用户) = {}", one, bingingPhone.getPhone());
            } else {

                if (StringUtils.isBlank(phoneUser.getAppOpenId())) {
                    phoneUser.setAppOpenId(one.getAppOpenId());
                    phoneUser.setUnionId(one.getUnionId());
                    UsersDO usersDO = UsersDO
                            .builder()
                            .id(phoneUser.getId())
                            .appOpenId(one.getAppOpenId())
                            .unionId(one.getUnionId())
                            .build();

                    UsersDO delUser = UsersDO
                            .builder()
                            .id(one.getId())
                            .appOpenId(usersDO.getId().toString() + "—" + UUID.randomUUID())
                            .unionId(usersDO.getId().toString() + "—" + UUID.randomUUID())
                            .build();
                    usersService.update(delUser);
                    result = usersService.update(usersDO);

                    log.info("将用户合并，用户第一次绑定手机号 user = {} 已注册手机号(未关联微信用户) = {} ", one, bingingPhone.getPhone());
                } else {
                    log.info("用户第一次绑定手机号 user = {} 请更换手机号重新绑定(已关联微信用户) = {}", one, bingingPhone.getPhone());
                    return BusinessResult.createInstance(CommonResultMessage.PHONE_EXIST);
                }
            }
        }

        AccessTokenVO token = userDetailsService.getPasswordToken(result.getUsername(), GENERAL_PASSWORD);
        return BusinessResult.createSuccessInstance(token);
    }

    @AutoLog
    @ApiOperation(value = "发送修改手机号短信通知", notes = "验证绑定手机号 11006、手机号已经注册 11026、手机号码已经绑定到该用户")
    @GetMapping("/send/change/phone/verify/code")
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    public BusinessResult<Void> sendChangeVerifyCode(HttpServletRequest request,
                                                     @ApiParam(value = "手机号码") @RequestParam String phone) {
        try {
            Long userId = currentUserId();

            String app = getApp(request);
            UsersVO one = usersService.findOne(userId);
            UsersVO phoneUser = usersService.findByPhone(phone);

            //曾经绑定过手机号
            if (YN.YES.getCode() == one.getBingingPhone()) {
                if (Objects.nonNull(phoneUser)) {
                    if (Objects.nonNull(one.getPhone()) && one.getPhone().equals(phoneUser.getPhone())) {
                        log.debug("该手机号已经绑定到此用户身上，请更换手机号重新绑定 user = {} 新手机号 = {}", one, phone);
                        return BusinessResult.createInstance(CommonResultMessage.PHONE_HAS_BINDING_TO_THIS_USER);
                    } else {
                        log.debug("该手机号已经绑定到其他用户身上，请更换手机号重新绑定 user = {} 新手机号 = {}", one, phone);
                        return BusinessResult.createInstance(CommonResultMessage.PHONE_EXIST);
                    }
                }
            } else {
                if (Objects.nonNull(phoneUser)) {
                    log.info("用户第一次绑定手机号 user = {} 请更换手机号重新绑定(已关联微信用户) = {}", one, phone);
                    return BusinessResult.createInstance(CommonResultMessage.PHONE_EXIST);
                }
            }

            boolean success = usersService.sendSMSWithKong(app, phone, null, null);
        } catch (CheckRunException e) {
            log.error("", e);
            return BusinessResult.createInstance(CommonResultMessage.VERIFY_CODE_SEND_FREQUENCY);
        }
        return BusinessResult.createSuccessInstance(null);
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "（内部）首页用户列表", notes = "首页用户列表")
    @GetMapping("/homepage/user")
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    public BusinessResult<PageResultVO<UsersVO>> homePageUser(HttpServletRequest request, @ApiParam(required = true, value = "需要排除的用户id，逗号隔开字符串") @RequestParam String userIdStr,
                                                              @ApiParam(value = "当前用户id", required = true) @RequestParam(required = true) Long userId,
                                                              @ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
                                                              @ApiParam(value = "页码大小") @RequestParam(defaultValue = "20") Integer pageSize,
                                                              @ApiParam(value = "创建时间") @RequestParam(required = false) String createTime) {
        try {
            if (StringUtil.isEmpty(userIdStr) || null == userId) {
                return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
            }
            List<Long> userIdList = Splitter.on(",").omitEmptyStrings().splitToList(userIdStr).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            UsersVO currentUserVO = usersService.find(userId == 0L ? 11L : userId);
            if (null == currentUserVO) {
                throw new CheckRunException("当前用户不存在" + userId);
            } else if (null == currentUserVO.getSex()) {
                throw new CheckRunException("请先选择性别" + userId);
            }
            userIdList.add(userId);
            PageResultVO<UsersVO> pageResult = userRecommendService.userRecommendList(userIdList, currentUserVO, pageSize);
            return BusinessResult.createSuccessInstance(pageResult);
        } catch (Exception ex) {
            log.error("", ex);
            return BusinessResult.createInstance(CommonResultMessage.UNKOWN_ERROR.code, ex.getMessage());
        }
    }


    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "用户群列表", notes = "用户群列表")
    @GetMapping("/user/groups")
    @AuthSig
    public BusinessResult<List<UsersGroupVO>> getUserGroupList(@ApiParam(required = true, value = "用户id") @RequestParam Integer userId) {
        try {
            if (null == userId) {
                return BusinessResult.createInstance(CommonResultMessage.PARAMS_NOT_INVALIDE);
            }
            UsersDO usersDO = currentUsers(usersService);
            BusinessResult<Integer> result = tzUserFriendsService.checkBlacklist(usersDO.getId(), userId.longValue());
            if (result.getData() == 1) {
                return BusinessResult.createSuccessInstance(Collections.EMPTY_LIST);
            }
            List<UsersGroupVO> usersGroupVOList = usersService.userGroupList(usersDO.getId(), userId);
            return BusinessResult.createSuccessInstance(usersGroupVOList);
        } catch (Exception ex) {
            log.error("", ex);
            return BusinessResult.createInstance(CommonResultMessage.UNKOWN_ERROR.code, ex.getMessage());
        }
    }

    @ApiOperation(value = "是否使用微信登录", notes = "是否使用微信登录")
    @GetMapping("/if/wechat")
    public BusinessResult<Integer> ifWechatLogin() {
        try {
            Integer returnFlag = usersService.cacheWechatLogin();
            return BusinessResult.createSuccessInstance(returnFlag);
        } catch (Exception ex) {
            log.error("", ex);
            return BusinessResult.createInstance(CommonResultMessage.UNKOWN_ERROR.code, ex.getMessage());
        }
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "是否群组隐藏，0:隐藏，1:显示（默认显示）", notes = "是否群组隐藏")
    @GetMapping("/if/group")
    public BusinessResult<Integer> ifGroupSee() {
        try {
            Integer returnFlag = usersService.groupSee();
            return BusinessResult.createSuccessInstance(returnFlag);
        } catch (Exception ex) {
            log.error("", ex);
            return BusinessResult.createInstance(CommonResultMessage.UNKOWN_ERROR.code, ex.getMessage());
        }
    }

    @AutoLog(logLevel = DEBUG)
    @ApiOperation(value = "查询用户最大id", notes = "")
    @GetMapping("/user/max-id")
    public BusinessResult<Integer> maxUserId() {
        return BusinessResult.createSuccessInstance(usersService.maxUserId());
    }

    @AutoLog
    @ApiOperation(value = "查询用户最大id", notes = "")
    @GetMapping("/user/ext-info/page")
    public BusinessResult<PageResultVO<UsersExtInfoDO>> userExtPage(@ApiParam(value = "页码") @RequestParam(defaultValue = "1") Integer page,
                                                                    @ApiParam(value = "页码大小") @RequestParam(defaultValue = "20") Integer pageSize) {
        page--;
        PageRequest pageable = new PageRequest(page, pageSize, Sort.Direction.ASC, "createTime");
        Page<UsersExtInfoDO> pageResult = usersService.userExtPage(pageable);
        PageResultVO<UsersExtInfoDO> pageResultVO = new PageResultVO(pageResult.getTotalElements(), pageResult.getContent());
        return BusinessResult.createSuccessInstance(pageResultVO);
    }

    @AutoLog
    @ApiOperation(value = "查询用户扩展信息")
    @GetMapping("/user/ext/{id}")
    public BusinessResult<UsersExtInfoDO> userExt(@ApiParam(value = "用户id") @PathVariable Long id) {
        return BusinessResult.createSuccessInstance(usersService.findExtInfoByUserId(id));
    }

    @AutoLog
    @ApiOperation(value = "修改用户的在线状态")
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    @PutMapping("/update/online")
    public BusinessResult updateOnline(@RequestBody OnlineStateVO onlineState) {
        Asserts.notNull(onlineState.getUserId(), "userId is null");
        Asserts.check(onlineState.getOnline() == YN.YES.getCode() || YN.NO.getCode().equals(onlineState.getOnline()), "state 值不合法！");
        Long backRunTime = onlineState.getBackRunTime();
        if (Objects.isNull(backRunTime)) {
            backRunTime = 0L;
        }
        Integer index = usersService.updateOnlineById(onlineState.getUserId(), onlineState.getOnline(), onlineState.getTopRun(), onlineState.getChannelId(), backRunTime);
        if (index > 0) {
            gyfTaskExecutor.execute(() -> onlineLog(onlineState));
        }
        return BusinessResult.createSuccessInstance(null);
    }

    private void onlineLog(OnlineStateVO onlineState) {

        if (YN.YES.getCode().equals(onlineState.getOnline())) {
            UserOnlineLogDO onlineLog = logService.getOnlineLog(onlineState.getChannelId(), onlineState.getUserId());
            if(Objects.nonNull(onlineLog)){
                return;
            }
            //channelId的为通道创建时间
            UserOnlineLogDO onlineLogDO = UserOnlineLogDO.builder()
                    .onlineTime(new Date(onlineState.getChannelId()))
                    .channelId(onlineState.getChannelId())
                    .userId(onlineState.getUserId())
                    .build();
            logService.saveOnlineLog(onlineLogDO);
            log.info("记录用户上线记录 onlineLog = {}", onlineLogDO);
        }

        if (YN.NO.getCode().equals(onlineState.getOnline())) {
            UserOnlineLogDO onlineLog = logService.getOnlineLog(onlineState.getChannelId(), onlineState.getUserId());
            if (Objects.nonNull(onlineLog)) {
                onlineLog.setOfflineTime(new Date());
                onlineLog.setSeconds((int) (onlineLog.getOfflineTime().getTime() - onlineLog.getOnlineTime().getTime()) / 1000);
                logService.saveOnlineLog(onlineLog);
                log.info("记录用户离线记录 onlineLog = {}", onlineLog);
            }
        }

    }

    @AutoLog
    @ApiOperation(value = "查询在线道友和关注你的人")
    @PreAuthorize("isAuthenticated()")
    @AuthSig
    @PutMapping("/online/friends")
    public BusinessResult<List<UsersVO>> findOnlineFriends(@RequestParam Long userId) {
        List<UsersVO> users = usersService.findOnlineFriend(userId);
        return BusinessResult.createSuccessInstance(users);
    }


//    @AutoLog
//    @ApiOperation(value = "test", notes = "", position = 120)
//    @GetMapping("/test")
//    public BusinessResult test() {
//        String phone = "15268545304,13795865853,18623095303,15102073271,13220838999,16643776395,15260216737,13345326023,15108835072,17364132506,18778390035,18384100410,18320752005,17784789090,18805235802,18645800434,15268251185,15955182564,15050562696,13680334865,13530228965,18895341068,13414831940,13201579173,18602566800,13513671921,17356674693,18237110570,15939067332,18370970687,15733183809,18322700329,18251250336,18743546318,13062789314,18709490409,18035736231,17609781047,13791691366,15882286265,19155253301,18759954787,13893430281,15214579246,18234756645,15174582098,17068105789,15951870792,17852640389,15074782686,15952135201,13052992966,15865901735,18347955129,15903492988,13761946092,18627561491,15173086089,16519331056,15118828971,17186120916,18848981990,18839379586,18682280096,13403413176,13544940836,18106850013,13116608268,17739020235,13660437773,15051965990,18845296620,17860577958,13933132392,13131372857,19916497174,13455308845,18369176055,13718549323,18929366053,17674072740,15854917711,13656862297,13612186142,15888622612,18856866007,18961117628,13474834246,17865186267,18232402914,18709427619,15663380025,18664012989,17353412073,17339768685,18846431805,13692027501,18328383821,13882605808,15908577684,18927526509,18943515150,17348674803,17756601943,15846753656,18394822596,13986919632,13565969004,19908590151,18914738530,17792189298,15890130903,15145974663,18378552013,18245192774,13861183582,15056379353,13007341099,18089390008,18069011546,14780287294,18065515325,18483601319,17363911478,18347504230,15908073447,18525603061,18255255217,15870278136,18972292903,18715513992,18646805312,15146835363,18156992047,13979220821,18700640506,17756619540,15944191677,13331786825,18755057923,15769208629,17355598974,15955547334,15712454201,13003373632,17309166965,13761127078,13291931381,15087298952,19923730058,18039650796,15965713565,13594067612,15933007076,15211017662,15680714596,18852128523,15979343372,18821793602,18935674958,15621182633,15688900865,18968187685,15383774286,17772282302,15532813026,15715669699,13253721680,18042995663,18742502617,13519683730,18745946871,17716711251,18302223192,13576121139,15043972887,13975145419,15736430854,18016393201,18355525710,18435145889,15903339544,18765970412,18524613382,15255270234,13787269773,13375297319,13570159902,17783280083,17732688959,18326618049,15090012776,13280027372,18969386015,18277928758,15573139965,13562289317,15395533915,13802410481,13935072338,18203406689,15589113359,18298953565,18087445233,13375742353,13601801354,18605462373,13847096500,13091774569,18629180795,15950232723,15929565477,15535476556,15656271230,18734394900,18826841887,18804267443,17639266792,15641562464,18247006363,18636303651,13572413723,13661794173,15291708607,18053939548,18095858894,18658390056,18935119803,15900964901,18667027352,17717184004,18227370125,18811473760,13684606990,18502864013,13841948945,16608680989,13721009422,17732668816,16651591535,17601350335,18521099570,18798203517,18155645797,15860275223,16637506997,13112729779,15732054566,15530969940,13589785100,18617360988,15521446901,13461631799,17398660658,15291938413,18961810780,15866713203,15002523952,13951729903,18873781516,13895440344,18342851420,18296773138,18956933966,18005302822,17611441695,18264616510,18982162862,13771442138,18806763066,13681332560,19882117628,13316854460,15185095896,13267076820,15062987471,15885007338,18255124770,17601015586,18515957512,17334535595,15873736574,13842264811,18842268687,13625696593,15393815446,17864738771,13260117730,18588719786,18281558840,18031693618,15359540072,13270138269,18993872302,15650725596,18114566306,15993423475,13609658906,18339929822,18173153723,18267278710,18750877626,17614190200,13657433161,18237729933,18325806323,18273374070,13622041335,13421023349,15623966636,17771446390,18653991256,15859076344,13804320373,13489922220,18870513939,18648185800,17686519801,18986116931,17816787295,15874952243,18841481956,18320997570,18321233305,18331959613,17687087191,13750695274,18175719351,13944863442,13727494435,19979667316,13908743576,18654058758,17785859857,15392084215,18826061652,15515710270,18292607236,18600531836,17879867471,18068351661,17611677538,15671617829,18166088481,13753881100,15695714356,15759760232,15991805032,15206720819,13968816131,13502915414,18282001320,13046093863,13368002240,18393840816,18418156658,13668897824,13003292248,13677493717,13590422694,18284301997,18759398783,13482636100,15393570327,18773545752,13897470900,17795058509,18690218758,13452080325,18632371415,18362219579,18347410072,19851599260,13212381303,19979623112,18555002048,18640212585,13320135829,18553159602,15021539717,18379864270,18623369739,15846179463,13150400305,18795007675,13243369193,17315098383,18112185531,15814443557,15660101596,13670222015,13692877231,17183001322,13845750930,13624905197,15116279110,15241250799,17366639829,15005861277,19197143411,15148526685,19850069520,13107384722,18841925652,15895856679,18341544363,13277698089,18686167462,13379080236,18337458978,13843074864,15907261155,15662698352,15395441575,13552352322,18854882186,13395655381,15319498781,13955437591,15737187706,13205402271,18856858858,13343133680,13901823467,15655257207,18353977545,13737514505,17326593970,13146074006,13458644717,15983552325,17323705189,15860306276,18947881890,19875799204,15901665627,18301982059,13809561870,15340512121,15731669569,15386938707,18511818182,18815161118,15700168411,18647443135,18910851259,18343306089,13596435070,15945724403,15139928170,15256209185,19967200337,15245778120,18088253615,18703147787,13070752019,18203406922,15378619917,13428124875,18879463069,18211088738,18435995321,18366849061,13947476387,15856280998,18124294869,15886532239,15109027917,18263805770,15201021859,15522681158,13546872655,18721330764,13574101469,13716704916,18910693221,18335402565,18916803068,13029914105,13675517620,15045670368,18673205507,18102042493,15001893855,15843002584,15227827161,13206043819,15886355440,18369512094,13006391302,13588460876,18253756910,13784761669,15317125174,18992829063,15905061816,18736795997,18870976309,15850770200,13797764478,15870099633,18879562121,13664840430,18866696900,15060037099,18183116425,18674875578,18222267624,13865425933,18173015326,13398385692,18352636903,15005168838,15108692655,18373706724,13016454470,15703007909,19848112757,13308583505,15737170700,15520567175,13667125580,15178944806,15873396623,13032485405,15573475672,18872200813,15350387994,18475142705,13851898269,15150231055,17755897665,13054601550,18961173705,18154098553,18850296585,13056493595,15554603681,13950096169,17341656062,15309413971,15971787139,18383903541,13393512970,15944609000,18523590730,18382612665,15882261179,18568726985,17835650358,18106766909,18332029362,18729265828,13323113386,18735208604,13414093550,17709608180,15338724524,13599527847,17568118693,15908031321,18366265942,15192087726,13456196289,15768338556,18954791285,15132731369,15900979453,18893415946,15689753256,18977484862,18764218095,15822117402,15127910978,18846137108,13234992450,17705565969,15092018457,15856950584,17744527761,15806303092,13076814750,17853591153,17385530181,15854228283,15813993802,18070909996,18447050813,13163341359,18843185133,15047877696,15705977482,18386618129,15343247726,13705692757,18109488726,18672575855,17854805612,13583991320,15563987043,16636187160,13308893182,13393165019,18022541635,13001521431,18831796117,19912773576,13376374831,13829022415,18281599379,18963984306,18126449919,18656750119,15012729193,15961599443,18018941589,18132756290,15123206536,15270765747,18335817509,18172825773,13971944411,13228129210,15950687527,15907375277,13207106198,17366169465,15773369893,13625969187,18065502799,17897264228,15735884639,17738787348,13859161076,15092983726,17051198370,18050972052,13570753413,13875161336,13657310228,13691146860,17799126981,15275207507,15650753851,15625030881,15164588088,18363060965,13871884042,13814818501,18758216760,15953986851,13629537229,15880991158,17345313759,17855547751,18944931440,13709245700,18019103206,13659339400,18874283731,15841544079,13439512671,15894785267,15685914220,18873535362,16627676343,15156193922,17880115632,18260419890,15231911223,18696968361,15040638864,15624380652,18891235669,19955332911,18816232965,15907823242,18310373168,18510829932,19852055765,18807066056,18201707556,15157504037,15886498736,13046270625,15756533914,18005667278,15043885198,15263967620,13739190254,18313892103,18844738392,18946279386,17531081691,13729258204,18907544033,18559069718,18255125102,18817930872,15043559040,15849614502,18935425797,15389064060,17776449010,15272804626,13644048063,15854872963,15800727630,13987800388,15695215065,15268144007,13762430508,13240161977,18165031965,18862158321,13057838207,18608892404,18734516963,18585530745,17860366913,18931078639,18182060126,13355794000,13945363246,18177919536,13879947081,17815549903,13819621189,13719790469,13867614922,13764699554,15516449186,13792423118,18288604746,18970641246,18009195391,13619905159,15389810723,13316920488,15383257650,17837080531,13308787556,18079077035,18192591625,18893210274,13855843727,15527810927,13675007294,18657451903,15879929565,13765577394,13847244664,15503555546,18435243168,13161295689,19928139892,18227598212,19831388221,15509841603,13450602831,15971526335,15017323855,18018531201,18335825046,13107230285,18067980685,13345992110,13559329070,15815866047,13253535415,13776643752,17640469313,15914075511,17835248401,15659083020,15110399864,17550510067,15118451037,18970759694,17877785290,13651336438,13615206708,18522643510,17702375662,13227129028,15864254669,18992546361,13865542482,19808431383,13663136012,18661720751,13208668332,17772361727,15953632662,18851970882,13137136521,15858252639,19969786328,18749670880,13414464239,13284997828,17321335118,13982251484,13207044102,15388314097,18926301448,18760396211,13797635377,13092758709,18235121363,18963641032,18928223251,17616855207,17860366023,18990934732,15117254621,13009083826,17309784091,15092972622,13131162677,13074794914,18317862976,16603111880,13479588482,13557336077,13093068067,15734537596,18820233018,13935572107,18351093999,18106574709,18164021542,15972982166,18224496873,13396411667,19112070738,18874843427,18193597007,15599662607,15170121436,15127173757,13298192081,18861979400,14792482317,18255513489,18226928046,15757130726,13201693365,17730376115,15648356579,18780460675,13717551809,18007735690,13104941708,13467816693,18518623957,13476916327,13858721894,18747059157,15609386611,17681949729,15730986656,13040221275,13681962784,19970097558,15700900559,17776007970,19800350617,13064299167,17700205448,18203557357,15136775510,18859238225,18355229157,13469582236,15859796340,18687563348,15650179824,18986108703,13452051033,13089009413,13855312413,13279408165,18722312302,18648250594,13035989182,18761403618,15009905571,17519243608,19918836108,15968684005,15304516858,15051836663,13241824754,17815015152,15528440540,18949123809,18146733960,18004528322,16673294290,18705905754,15535400024,19933846921,15630663600,18520032203,15179072992,18866191176,18857324360,19917842223,13331975387,15265325896,15996126917,18076573340,15950687544,17717340148,18853365262,18258007879,15962311860,13731784841,15662199796,17780270467,15001851997,18327657112,13922152951,15769450002,15305567080,18013973731,13986116416,18729380830,15050842637,18850529469,18065762666,13790240908,18915221451,15847462527,15816797595,15634058269,13617096624,18793377439,18951679756,18771180148,13233763867,17059443023,15086464826,13022707025,15901533761,15764541788,13052905716,15753891101,18919120800,15776809575,13896578799,13042430709,15192698623,15257606667,13917606823,17763316000,15512214955,18506249146,17631369608,13990387479,17320257488,19990556252,18351864562,18852023725,17853130304,17802586068,15768311042,18907548669,15521142048,17718134404,18860424296,19963609315,15948759623,13751931196,13387722877,15153858326,18397700925,15762058906,15028595108,18011613090,13681274232,19861902360,15659351433,18404710685,18569713536,13597591720,17806238029,13995683173,15195026246,18373596582,18669912683,18915738517,15288481268,15639610806,13643116519,15965712781,15731334217,13888965882,13524085660,17745161633,13681254872,18923183467,18370524135,13054334068,13189357389,18129283256,15572013283,18206308217,13185588280,18250969370,15820450976,15938833753,15579139521,15866332169,15501725937,15554080553,18810929080,15277450403,13211607560,17861409409,13220532665,18981061095,18092001826,18520480398,15751007726,18925328087,13268702049,13685180951,15194431980,17358863365,17354311192,13222293777,17863017038,18130588891,13563026049,13316176211,17336325262,15844796641,15771110185,13015494472,15242919842,13378809370,15099312171,13163724540,15256026290,15145907373,15573978129,15264318150,13151067675,13733034070,15112333708,15529172521,13654247810,15959463777,18320043599,13394048506,15088164753,19977963883,15510098535,15146817057,17791522436,13680687270,13834601857,18327062306,18086435041,13751720563,18864982536,13918720754,13949988859,13632048958,13341196753,18213307819,19975966102,13102371218,17862557462,18022285931,17310032305,15340656110,15172313411,15904007396,13878346935,15573423959,15053377930,17661351505,13313184006,15997972820,18811571877,15246007822,18643980524,19884532993,18605892038,15073177842,15941255368,13313118155,13568041180,18398631905,18796299299,18715629170,18660883765,15647295498,15873199245,13417776193,19881199021,15159398672,18350676377,13990548204,13082961999,15318646681,18277410826,18214723469,15739625135,15020137213,15347085919,17795140135,13977404838,13616398572,13657732019,13611152179,15852261245,13739939279,17881107808,13256440826,15725118398,13830467568,15323243231,17815151123,17885033004,18810911255,13833313389,15612723017,13640166718,13548491944,13356829521,18959813028,18712238236,17820259281,18679265152,13717673485,17826180603,15579012569,15084380688,18765570757,18369761878,15956352870,15806410512,13166181231,17879827535,18214600560,18842395578,18909509937,18979463292,17515286330,17833111776,13066018812,15829053294,17366699908,14789888630,15602022355,13619638867,15316061190,15231091679,18942439296,18054629302,18730389336,18259537628,13772694651,13827550566,18936250227,17381013290,13516775325,15860251040,15298029584,15165086120,18985388027,13612825858,15387168696,18245976606,18735947310,18906954336,15535308266,15775812511,13670874230,13482237294,13654757036,18692255837,18093194345,18511836540,13230033102,17550318620,18231205985,13637684318,13711166391,15822244082,18220180376,15559303357,13535117544,13085333768,13857908397,13240872722,18867473358,19141277395,18151922526,15035268824,18901458027,15895620056,18922068973,18832031305,18814465895,18356121228,13136421135,18041109707,13939163085,15893555092,15626871907,18103602036,13268052617,17713599327,15953740091,18985680578,16736454372,18852089692,15049373985,15089709968,18086207699,18568753079,15230313858,15619968152,15699253567,13166904095,13632347461,15275745624,13964258712,13328629120,18803436585,13203138920,13061415015,18435162460,18893531157,13889534917,13706754350,13627033231,15134291630,18589627681,13171825436,13815253707,13861198325,18304070769,18090110604,13525888956,17691066887,13714863167,15154211013,13123884893,18476545321,18845738007,15181413673,15201856843,15877321985,18146421897,18559759381,18026110223,15557406770,17817217272,15546636251,13795461349,18895340490,18629146832,15057858649,17088166729,13575709143,15526331077,13339915876,18485654692,18742066547,15181116427,18635813335,18587877829,13414917947,13715510520,17835098522,13941313559,15018866836,18643740568,18640585816,13078928582,15053998247,17622367863,18796177164,13346178076,15135565785,18080647742,13959636727,17351034292,18676104898,18335746258,13303409166,13205034401,13231721916,15317102071,18368297515,15968303696,15821571184,13629928723,15997525645,18252081870,15588450975,18268677670,15721431936,13195118740,13217067769,13386866070,15735172515,15841297221,18435137050,13545541844,13001766015,15983941216,18266032279,15398558778,17703883769,15127139710,15911103218,15257741650,13681611502,15306618778,15895933881,15261599002,13277254026,13564525080,15391607865,15897576796,15640512248,17858778807,18318546081,18331162802,13091371689,18298318156,13640358077,17631987862,13245974330,13430099288,18335821553,15179181972,13518241765,18770815357,18345993263,18136270302,13678423202,15756125041,15273119798,15291723020,13799380391,15164300813,13110089619,15564196901,18379455183,13158008963,18628060591,15689923507,15040070365,15033057917,18171932395,15502210190,15739374052,18912089160,13876325891,15541773103,17640449487,18961275053,19907948935,13601506145,19162728767,15636117820,17837807600,13619566652,15896157833,13320197728,18120779767,15971334356,18181253392,17353641446,13836161298,18870152597,13904823099,13060056215,18846086281,17696707454,17777922515,15885359373,15992687507,15097740445,17772701386,17331287836,15052932073,13862317059,13474738947,15287080692,13850151022,17858953983,18012939146,18551610131,15384045239,17815787904,18601353707,15163121661,19120320836,13555223504,18116802557,18028698431,13710827309,15955138085,18268938943,18201708717,18377172241,18350099519,18279215993,17876831819,18373169622,17796563262,17860713715,17614339793,15179124870,18307189544,18889186235,15921573262,18030558408,17569153133,13524366678,15520819018,15238549584,17305602536,17769398711,18627398711,18104363382,17862811711,13908174958,18588429991,13262259061,13561545152,18367377321,15035082725,15000223665,15207916575,17344671287,15543552698,15661069650,13820972560,13912393786,15093075260,15229933278,13592483980,18845071376,13722273624,13643439647,18328018192,13842688858,17843107494,15532821133,18372563186,13942761220,15233253818,18261213266,15574947343,13588627599,15021605146,13973031770,15718547984,13398109192,15809429510,15855226905,13865645313,18871162687,13632316376,15006489673,15306991640,18957813218,13201225126,13594462529,17790633010,15233436311,18862017180,13076896699,15647921018,18936761793,13962133392,13726297360,18257922627,13968337966,18297721869,15020916929,17738148971,18222815137,13099541511,15688269885,13325274867,13249180678,15708224410,15269789865,18583725698,13760888871,15735108878,15327337239,13472733116,15637187807,17693141362,19845417679,13322934753,18351282598,13783118576,13837930817,15037717384,18253257028,15134483459,18931858122,13302928472,15232381709,15019809219,18810309959,18797412787,18980639193,18158813385,18100347950,13893164924,18380329683,13940464560,18705530567,18309467710,18935392360,13692689182,13809016859,18682206317,17659916763,18020911376,18319599781,13287038756,18941305870,15551287137,18992359911,15931086521,13320530526,15805385544,15585076085,18200457899,13661501132,15755467582,18360877087,18026720459,19155052425,15180011630,15221372353,15234687935,13465832063,18285797505,17815261648,18644961553,13349112683,15008625872,15807593764,17863805392,18846154159,15528016256,15862743856,13321227839,17789896284,18060853327,13562104945,15695168941,15840458106,13967806242,15955372600,18610457142,13767360472,15594012831,13707004409,15280118081,15516190571,18177771831,18080372297,13638119378,13751658946,19150211462,13946849875,13539680565,13612926851,19977414577,13316715097,18865579926,17875515488,17723040446,15554116665,18107133963,13081651319,18645484906,15033199338,13778341038,19829789098,18602577973,18671128270,15618510801,18680602204,15599899685,15206090409,17674777713,18435608256,15960689219,13136451993,18859278175,15136763668,13360394720,15504631819,18387129576,17798569716,13949155920,13701753304,13091449652,15225813060,18355342810,15318751029,18375085702,19959363893,15769653900,15553916679,15682032990,18382286385,18267599703,13808058510,18950903038,15524276261,13957669150,18105415685,19823302975,15030547268,18707715819,18260730085,17398388243,18428369497,15001854136,13117808609,15297391762,15243621226,17858503959,15285174300,13165223590,13515361675,18035982203,13105374585,13619569706,13931574567,15170474606,17771663643,15542704600,15344644976,18623023510,17371252660,13367377199,17376666609,15867534597,13600978310,18788170120,17810244494,17789285239,13739406890,18093503474,13205412473,18956189756,18948188821,18389664767,18956770832,18215128757,13578755107,18780317776,17379178112,13125179932,13299906512,13514592689,13235389241,18935715828,18768218192,13170269605,13606134176,18372610061,18217602512,13104311447,15075628573,15862407580,13888096567,19832107365,15214819608,17843122450,17719182108,15064238683,15196895295,18381532564,15052220861,13936581031,15079868887,13955789549,13720004627,18718515608,17664669737,13851564162,13782209096,18630755070,15516901218,13634747796,13309332213,18846667571,13231493481,18850953977,18327836839,13892255568,13570513133,13667018015,15270117416,18858511309,15776583819,18159616388,19137866057,13463015853,17838677051,17317718981,18625728911,16622909828,13842062976,17758855533,18893413946,15255405008,15385211983,15264253385,18708787021,15945722966,18979432645,13967765215,15269107297,13751372046,13623722823,18772103051,18380392307,18511812005,15860506886,15222453855,18296162949,18115351534,17773973323,13166514191,13603044101,13855943877,18659181706,13372024723,18990445617,13021228431,15859150900,18727505881,18780148067,18292263765,15170019177,15908952478,15231145233,15943793678,15851762679,18751326140,15392020267,15923761244,15283141943,15652480057,18795877750,13816710546,15914526990,13672342370,15621644078,15356164757,13054791967,18952149220,18473488871,15960995377,18355371038,15562186963,15171638512,17858513225,13912109661,15123684650,15928040976,18896393042,18203943661,19936467899,15823721960,13982870757,15972179246,15659803957,13363545525,15863381071,19904457190,18923042537,15903651448,18121502068,17692458165,18332977715,13705035021,18960157212,17785427535,18961671396,15057596532,15230310626,13543010964,18479264036,18350122511,17862471129,13569587303,18741930678,15846059676,18722287135,18373293953,17367906953,17853602291,18626793511,17334046109,18139605881,18501274551,15678871824,17752673247,18526592860,19976989617,18063730970,13328503738,18194068816,18516709081,17137797994,15953750110,17191917455,17096414324,17150522475,13870490896,17096414482,13533225160,15700122326,17150522460,17096414261,17134025278,17137366423,17137365040,18369830282,17109324200,17134025282,17109324203,17109324212,17134025323,17109324209,17109324207,17137365084,13782388509,17137366584,17137365047,17137364836,17849661204,17109324204,18842334149,18279240857,15916473127,15303789103,13546643366,13253603585,13573455307,15142064530,18054371615,15005992835,13171950841,18437905958,15879715928,13726486948,13718528122,18379784671,13177127578,13571261361,15651621238,15184474870,15132791191,18870092314,17186505566,15720511107,13175266921,13780139788,18846832802,18248690058,13597662960,18757095347,18226915787,18790163692,13668177163,13210510235,15847565848,13789614309,18062531023,15014116366,17321272150,18734627402,15002409266,15257062902,13546825519,18160494571,15595218052,18851690877,15987124912,13373997740,18319103458,15995297909,18575251331,18903825125,19828343613,15732404229,15840305166,15236201568,19921171348,15823837320,19187680581,18002649640,18508941837,13225768563,13309886538,13866001765,18754703869,15267765882,13762432961,13110607532,15074746882,18181163478,13504759235,18075459153,17788173250,19854190090,18665218528,13381696703,13576954772,17755329301,18055173893,15694881013,18365186450,13261889622,15083618611,15966675446,18842151596,13025145490,15378127332,18810820602,17736830855,18246374962,13702552028,15320196035,18147452471,13306341197,18728477154,13917403795,18147341448,13519598554,15811945694,18692936626,18051960183,13153104777,18347940314,15015241520,13586740148,18876088237,15902909850,18835239374,13806908784,15254137391,15563359693,13879003189,18667376933,13897047817,18853872815,15075262347,18746515376,13353084346,15192570867,13485580359,13831775761,15960230527,19153103121,15754930323,18879837761,19108474419,13733006222,13856057349,13862683723,15932876624,15109513514,15555759972,13603868847,15094873302,19987232521,15576296959,15285918261,15874783324,17723056848,18011098971,13979140409,13530589887,13033916995,13132070217,15882732209,17701229051,13663623212,18374985320,17879362095,15079408463,15172360625,15871609033,18117825021,13859667602,15048401852,15172561518,13373796623,13863001310,13851237661,15930060239,13919255537,18121440509,17860161601,13790994467,17829633638,17717348237,17851143107,13355568937,15279161791,15092105373,13069031771,18890026805,18641619986,15228739136,15984510352,18891407290,18757021280,18988574907,13871040776,18559652028,13032888208,16673434556,13242434328,17380931126,13913669123,18516538618,18994466044,17865566279,18783449283,13946330202,18994352383,19906873526,19141288623,15535543568,19972516606,18235483973,17854233117,15760953778,18266924066,18050195227,19832760957,15653491537,18071410603,13489073084,18515950828,18221791328,13280857727,19847673129,13833181973,13302135187,15062828533,18269215631,15207992446,18065111081,15806681196,16655179611,17354130565,15091704150,13913540864,15928450782,15816284320,18093257216,13976742909,18870187520,15501415176,18390061601,13011985087,15920495841,18920060329,13453232992,19834126883,13103736858,15073255507,18896962012,13784768659,18611851651,15091664620,15730874346,13318763125,18117215093,17815090772,18255903390,13347381126,13753061079,13810267769,18616500434,13486086112,17321024140,13168821508,13068982784,17663217640,13384862298,15552608795,13767811830,18437753672,17776368810,18235543757,16607000530,13397050244,13357162640,18532516283,15952709386,15532967881,15710153453,13752503536,15387102582,17350324610,13611916029,18358708533,18439410957,18971232341,13517009622,19979401754,15801607729,18914836888,18200737816,18675121162,13008532012,18664394621,18264499089,18273727890,18296943201,13476880213,15994827345,13302777909,15159387189,18052649051,15728280450,13992499966,15055031388,18053724086,13347807273,18903010858,17734823000,15546408169,13191921785,13852070283,13656657835,18301560821,13116690753,18810995011,17853726736,13213018637,15909337529,19999212551,13870307695,13636575060,17656605170,18878783165,13029352629,17818233631,13576027101,15024996810,13934079676,18367649556,13198469975,18933159574,13427262869,15259170460,18764718667,13305566637,18278047215,18399393854,15570636026,13607504922,18912150657,18601126412,13667960397,18643345981,18571497731,18144802646,13422498781,18131227341,13672877501,18505483071,18907486126,13945694421,18968195986,17305572006,18403005304,18262011040,18350114098,17552746744,15016457218,15339150777,15723052074,15508179806,17621745603,18060142306,15522009497,17855417858,13698278304,18329134104,15683962572,18357893782,13068116304,15169032576,17697271659,13305442916,15638578381,13365566191,18030248197,18179110426,18963193320,15999308708,13916994076,13927469102,18220927859,15021199751,13332589957,13034356683,14797363584,13960435883,13051050480,18872092114,17737491120,15754519524,18858075422,18940858220,18064767977,15158281342,18384916507,13957475161,15922713147,19151321805,18253558981,18994889960,13516994638,15022952844,15273267789,13788904608,15639630105,15828814360,18729627809,15770547617,13397099002,18658102021,18009620901,18701189968,17798231411,13103703774,18827558080,13929248805,19168860562,13918471780,18356181560,17698785838,19833781158,15603751007,13920573228,19993865325,13006580177,19971486499,18993811990,18475241313,13501287500,13631913349,17775309289,16605309379,18635359611,15380615097,18033366638,18846166540,13465747232,17398376732,15593391881,15254461830,15100030385,15246996046,18315250910,18803565790,17331527361,18845611782,15949850772,18643493113,15933801019,15566545819,18715650128,18310355648,17322834020,18711122976,15947064889,13180561195,15982302042,15838657036,13913915325,13063298896,13087225717,15033689017,13582934193,19903185165,18833710889,18771945977,15245840496,13576591968,13738083774,13889410236,18146677058,13728030421,15192006202,13767717328,18271387069,17338647968,18835942188,15886355699,18856358276,15038616396,13655484145,18950195037,13627491722,13821396563,18959419063,18035191054,13654576161,13643897987,18323332078,18982456547,13173817163,17342660826,18500473383,19834037701,17318307689,18868982366,15890070235,18852133086,17635972586,15328506723,15856382614,15328508137,15706059585,15724535974,18056713683,15813867155,13023028978,18984622130,13791622386,18971067271,18781911498,15825655607,18932250360,13270232389,15216885625,13078036535,18707487595,18692031264,13952817951,13588010511,18641662022,15225401776,15054116616,13980346978,18750377320,13173049953,15238568269,13536725639,15013384778,15197337563,18832553505,13108631197,17339836207,18895685722,15547829886,19958618365,18193382826,15882539327,15291718267,18049069839,15180721552,17663757719,15936989611,18652033557,15071138724,18725678489,18710316239,18801177839,15216138866,15005917099,18983141099,13732073779,13947829065,15360205903,18910851321,13867969618,13319176623,18500973588,13963013605,18810352015,18066063851,13634360842,13180522543,18968346465,17537612209,17310568973,13204764387,18029169526,15234210494,15906558433,18863705607,18283698901,18351408107,15009091768,18149515545,15910253018,18013601355,13321556665,13750432082,13753709030,15267309752,13705167906,13906931599,18983874336,15628697200,18520881123,15884471041,18746333625,13393313154,18322065496,13765714539,13302132616,15838207867,17323662836,15163096511,15872420770,17616101671,17775797052,13011418329,18697758008,17816095317,15218533011,13944675538,13198829987,15645119308,15571365583,13910674331,15884518364,18786039525,13897669141,13803814368,13693132934,13797158769,15670975825,13191495545,13811556213,19850159116,13962216579,17797605894,13663510464,15556655237,13818201953,15200091520,18078792483,13519408881,18751328785,17516475785,13610057662,17816594932,13840134785,13820135906,18357125080,17681888246,18800296958,13853771905,15049905289,15136193616,15377991823,15759166926,18915058256,18959786218,15377953856,19142756121,18305293030,15108795577,13803411273,18739323952,13012665959,18819231503,15703410069,13785813667,18595257876,18382895385,18935323570,13776876105,15007985180,15809214774,18009035605,13011588549,17394788851,13188966309,15246206101,18639332801,13725251200,13979951750,18753968100,13972491640,18645819771,17872009790,13217925950,18158611226,15848282223,15020375769,15684559461,15037940380,15822633570,18850401970,13794323668,18773124030,15320080162,18966897505,15502726935,17315764639,13349480826,18161189689,18986107251,15610150090,13037056566,13572889163,13670466151,18406594606,15159879601,18353229658,15866728801,17375687690,15650146396,13420961330,18651634839,18268920254,18718965119,17516105166,18200168751,18801100591,15058827965,18069272529,18739395153,15759015218,17711220198,18861875929,18167213653,19989091082,15854203123,15083713215,18202990468,18935931573,15168124978,13976773336,19805476021,15381430031,18638208262,13916957340,18334230276,13541325076,18296585152,18563776641,15058218866,18909567577,13734180826,17318597635,13726602663,14702882456,18028704391,13716440532,13525759697,13355115497,15169741908,13013958711,15973250080,18230021123,18745399086,15829129903,18370790130,15764011150,13180990232,15867018288,13868248189,15813232179,13229422209,18853116759,13179987603,13051423756,15369601626,18890765821,13907250343,15853239476,15217709143,18362388771,15801849817,17767872389,18738078777,13299216987,13217425596,15934267783,13105200480,19801193885,18370785277,15809004607,18186573959,17851576288,13922685273,18434775672,15333461028,18133571373,17326049993,13282109360,16603183609,18843156289,15254121381,15563376065,13625724637,15857215361,18458365561,18731873010,18737163909,15560106695,15213063069,13370554919,13461712197,13121895733,15588003414,18638226013,13505436368,13039164891,18208814613,18835211671,15072331509,13025682262,18032564109,13593431059,13682517783,18290033208,15539971976,15980113005,18950448599,15145094871,18262838257,13973213808,15565818985,18275138304,17693249120,15705050468,15984592420,15939380486,19957135860,15951083716,15969427501,18629994880,15016151774,17783720624,13757585118,19159362339,18638849895,13759902443,15951287765,13956542210,13583372965,13661051889,19898617829,15114283205,15868596746,17864274265,15382688159,15014633173,18966533395,15327256130,18851762189,17781537005,13504137628,15735621910,13394542200,15229399061,13755369500,15985494442,13969903919,18842943160,18343393393,13312918702,15004584458,13524128450,13354633606,17394947786,17339836338,13259966297,18045888662,15947377326,18830293440,17859015873,13166112598,18335239118,15371553365,13706943416,19832165051,13379438970,13026570865,15665256056,17376505573,13304069939,13609209763,17739787413,15999120840,13385430800,17718702209,15304363143,13356678514,15037645579,17673978723,18670139261,17727962175,15658919926,15642138177,13283347520,15167881359,18348491663,15330233529,18719866879,13224282946,15661488769,18761897230,15230352658,18834952668,15839330619,15570138331,18255595796,18568186675,13869380962,15990686284,18109789192,17375018385,18134282839,15530771980,18174017395,13912960316,15126378218,15755055886,13420792867,18513966884,13461910647,13613888565,15926359330,13021805005,13587466960,15502259519,15059670287,15896422318,18334582895,13596213990,18810684538,13327432900,18601538042,19959355179,13429641520,13824329187,13587887032,15638353968,18963192709,17771614231,15175210947,13176899752,18819421536,15862224803,18092757797,13936998095,18892682642,15942665978,17663631489,13187359028,15914766050,18322466690,15380964350,15220778338,15241558445,13965128962,18303282853,18819356045,13552647782,18787475278,18503830112,18966844205,13273151730,15901225076,15144063578,18520700926,15770871151,18380909076,15163142072,15922262033,13091884469,18257170988,15506050203,18833543996,15267666873,15913984574,15533171815,17318687787,18890669558,18956324635,13397857392,15254692001,18197976363,15124153157,13854002211,13681756489,18918248775,13804752121,13301502770,18349158602,13349211530,13558666703,16622195161,18907429395,18157222971,13816342554,13993426091,18312288742,18217034168,15733944633,13521635676,13281971603,15889110366,18595538756,18976218208,13632184923,17730127701,15110267005,17747078020,15007602659,13472230464,17305601037,17738638629,18905237932,15156006897,15073697169,15239933132,13696901002,18794988110,15189558619,18393601409,15718298055,17710360520,13313512548,15806441069,15215021939,15566555566,15717491287,15192468802,13673038852,15778664838,18815424763,13216165086,18054971612,15232252297,13206569602,15621837238,13700725833,16698501951,13598119332,18939341096,13455017053,13777452229,18099139827,15042779730,15152717263,13886790872,15931197437,13640946583,13355157728,15841739056,18993262906,15900240109,13029501669,18260067283,18109500935,13085281186,17700704034,13317197260,15048926258,15348872169,15982281534,18625647080,15170016979,13588714626,18454804170,18080057849,13973321359,15211784901,18042633577,15920163699,13588064066,17806097628,13786828165,13816285306,17317820226,15990072428,15275857923,15523423255,17558071975,18112627254,13953644987,18193052710,18728801276,13600253663,13525606330,18381661569,18245072738,15821806681,15979645428,18058701200,13461699197,15235150636,18165362707,18255202536,18222525247,18306012006,18866647315,15171696974,15502638038,15192701072,18228599767,13335667167,13207148052,13414860768,16673283420,17733705985,13935135475,18217901769,19821209414,13478702180,18742516618,15826047656,18792763253,18863978132,17686623327,15888982013,17863529006,17627839895,15382169062,13771887220,13717664056,13885683575,18522489757,13885550081,13266025747,18770748304,13942612382,13938327422,13970032358,17304077670,13231377753,13159155392,13856320524,13314111188,18904737239,17755003850,13726551337,18177871313,15775965286,18351580952,15995295532,17863919308,15040138441,17828878631,13655092198,13106051568,15338355917,15929013886,18746029893,18615340988,16638210340,18105918225,18602557672,18210817137,13371922328,13335122130,18940953983,17871926770,13163390901,15688896091,15921202624,13180030141,18315201023,13694723636,13080330533,18270362047,17852648412,18869713675,13627090864,13702360805,15820140662,13517922100,18398503694,13612028786,15528091618,17843093530,15955690446,17860722925,15850133862,18246311398,17303415431,19897007972,18622697776,13339544139,14784577717,13782717026,17791536001,15922052384,15988861017,15955763600,18386626240,13283712463,18062034912,18262637297,13198796898,13686118221,17858750959,15981091944,18339161077,15907908238,13350369685,13390442133,15313326127,18875425941,13571587726,13522396413,13552124043,17784270942,13943551881,13525628729,15205636669,18017185567,18867157381,17342012787,18743468582,13657045366,15371503739,18642943500,15149115601,15880281270,15061717806,18077303938,13856745108,13751041436,15116223557,13766328394,18084961997,13935750850,15228761792,17814778309,18780744007,18984423590,18458225717,13913618365,17879588488,18920623644,15869646701,15281341561,18102751995,18217268442,18049528252,15378052004,18888641471,15305559582,13202057358,15694915539,13509073859,13619805762,15262527656,13940782825,13799737002,13545749745,13267950190,13671019119,13409213976,17302836965,18350037659,18991601771,15217032937,15588851093,13510593409,18868117822,18038009927,15334228315,13130393365,15130078072,18360931613,13627277785,13196765532,15972955828,13611812607,13207589762,13397676231,13997717893,18703323900,13518755308,17784210789,18436015205,18149257670,18529422964,15965380128,15967773647,18280188409,18358314182,13210107489,15121065181,13670322856,15007605259,15303897379,18032306808,18829337654,17385830561,17386811873,13644695347,17730045501,13548994440,17761705870,15010991347,13030435446,18899466273,15979966849,18013990256,15283779720,15995717517,15704663346,18232465166,13226331847,18726780991,13953992004,15972668627,18281043898,19916937657,17096235871,18750657997,15256977745,15128514501,13149180077,13684687728,13091378440,17735761002,17362127190,18041290622,15725284259,18685827879,13461723152,18097488065,13761378413,17373628783,18635182139,15600907248,13002420767,18174298707,16606123967,18237227440,13913607989,15272544619,18908581537,15756173361,13638525431,13771764245,13384596579,18735190339,13247662849,18043156669,18096656126,13220909173,13671531343,18410941919,15013688184,18270855806,15203363384,17307451679,13710482986,18781195990,15178118169,18545555153,15232959138,18698468577,15774340251,13709735153,13767355578,18054558816,13351847726,17805859323,13615013535,13593239101,17710600736,15730771962,18701121185,13214639872,13386841547,15858938212,18166225250,15048459627,18163709120,15055147383,15852504227,13210228350,17662520795,18516777831,15526548769,15717393569,13612618686,15209828197,15844185232,15072418375,13578831187,15099788554,15275749622,18191524315,18921209161,18811155624,13903813551,13398390092,13903939061,18270531230,15051274165,17380370542,18338086688,15521414645,13525402977,13938308753,18558768207,18331333424,15681518320,13105163831,13755432551,18216489398,15399914442,13396959060,19818966497,18358161193,17852352536,18104317569,13124112328,18817801783,19976854506,17689661978,15236630356,15161328669,15311486323,15172693026,15003457925,13361089956,17760876561,18016236027,15981318466,13388009659,15765533854,18611691481,18796638796,13764681596,17705965811,17791921542,13889311397,19182922902,17791967608,15107156245,15657171585,15101097734,13461359060,19976060728,18135109407,18006740618,18701904637,18804671071,14780133575,13654688977,15835316086,15235316186,13352236961,17625320570,15893417634,18483614725,13908072411,18914770876,15508898818,18856270285,13520240839,13089168318,13305763025,13633712858,13561660083,15580139880,18171335548,17878574308,13623631980,18107977783,13089550503,15156815053,13880716724,17602107689,15015349345,19853148744,15951150290,13933637021,15857166982,15824509680,15998408035,18685165280,15188374567,18007529871,13577498083,17732514395,13251983755,15536890878,13888631259,17395991766,13558795246,17852670863,18917567801,13684533162,18639675725,18518537568,18294044855,13285584530,18381812707,18249504207,15005603907,18679909322,15938862031,17658085803,18382886907,14717731543,13102704717,13305547191,18552889918,18091523251,13728882813,18084772202,15959031223,18849870029,15389239902,18955563668,15655709158,13862666362,15932202648,17721056686,18266209887,18526418374,18357856115,13633395275,17749195684,15771137917,15675801734,17683707128,13603833981,13762514717,15616320402,15020238088,15562893032,18739359140,15083809679,13615123618,13849300875,13075380951,15623700025,13559608733,17130338687,13981460961,15991847008,18078151677,18283958376,13824682093,18189548387,18920781039,15205163040,18855487416,18538815205,15342252591,18845464697,13714744238,15514022627,17806788625,17780518059,18571489473,18202026432,13983804913,13884329805,13658674006,13567936322,15173287785,18233162858,18468166558,13891497459,13014498189,13820979967,15674183141,15808029640,15816143769,15143575962,17795440069,18998985188,17339800029,17091147693,13611951833,15779737216,17599285267,18855133908,13518712811,17350186860,15010985259,15203397926,13659349737,15822718073,15203828125,17863117679,15541685123,19828456648,19808393834,15845446704";
//        String[] split = phone.split(",");
//        List<String> list = Arrays.asList(split);
//        list.forEach(o -> {
//                    System.out.println(o);
//                    usersService.sendSMSWithKong(o, "同桌安卓最新版2.3已经发布，为提高使用体验，请前往应用宝或者各大应用商店升级。点击立刻升级：https://sj.qq.com/myapp/detail.htm?apkName=com.sd.tongzhuo");
//                }
//
//        );
//        return BusinessResult.createSuccessInstance(null);
//    }

    public enum TestPhone {
        //测试号
        PHONE1("13800138000", "1234"),
        PHONE2("13800138001", "6666"),
        PHONE3("13800138002", "1122"),
        PHONE4("13800138003", "2233"),
        PHONE5("13800138004", "3344"),
        PHONE6("13800138005", "1324"),
        PHONE7("13800138006", "1423"),
        PHONE8("13800138007", "3124"),
        PHONE9("13800138008", "4213"),
        PHONE10("18300001001", "1001"),
        PHONE11("18300001002", "1002"),
        PHONE12("18300001003", "1003"),
        PHONE13("18300001004", "1004"),
        PHONE14("18300001005", "1005"),
        PHONE15("18300001006", "1006"),
        PHONE16("18300001007", "1007"),
        PHONE17("18300001008", "1008"),
        PHONE18("18300001009", "1009"),
        //小助手，测试勿用
        PHONE19("18300001010", "1010"),
        ;
        private String phone;
        private String code;

        TestPhone(String phone, String code) {
            this.phone = phone;
            this.code = code;
        }
    }

    private CommonResultMessage verifyPhoneVerifyCode(String phone, String code) {
        try {

            if (StringUtil.isEmpty(phone) || StringUtil.isEmpty(code)) {
                return CommonResultMessage.PARAMS_NOT_INVALIDE;
            }

            for (TestPhone p : TestPhone.values()) {
                if (p.phone.equals(phone) && p.code.equals(code)) {
                    return null;
                }
            }
            boolean success = usersService.verifySMSWithKong(phone, code);
            if (!success) {
                return CommonResultMessage.VERIFY_CODE_ERROR;
            }
            return null;
        } catch (CheckRunException ex) {
            log.error("", ex);
            return CommonResultMessage.VERIFY_CODE_VERIFY_FREQUENCY;
        } catch (Exception ex) {
            log.error("", ex);
        }
        return CommonResultMessage.UNKOWN_ERROR;
    }

    private String checkRegister(RegisterVO registerVO) {
        if (null == registerVO) {
            return "注册信息不能为空！";
        } else if (StringUtil.isEmpty(registerVO.getPhone())) {
            return "用户手机号码不能为空！";
        } else if (StringUtil.isEmpty(registerVO.getCode())) {
            return "验证码不能为空！！";
        }
        return null;
    }

    private String checkUpdateUsers(UsersEditVO usersVO) {
        if (null == usersVO) {
            return "用户VO不能为空";
        } else if (usersVO.getName() != null && usersVO.getName().length() > 30) {
            return "name 长度不能超过30";
        }
        return null;
    }

    @ApiModel("手机登录信息")
    @Data
    private static class LoginVO {
        @ApiModelProperty(position = 10, value = "手机号")
        private String phone;
        @ApiModelProperty(position = 20, value = "密码")
        private String password;
    }

    @ApiModel("微信登录信息")
    @Data
    private static class MpLoginVO {
        @ApiModelProperty(position = 10, value = "微信授权code")
        private String code;
    }

    @ApiModel("注册信息")
    @Data
    private static class RegisterVO {
        @ApiModelProperty(position = 10, value = "手机号")
        private String phone;
        //        @ApiModelProperty(position = 10, value = "密码")
//        private String password;
        @ApiModelProperty(position = 10, value = "验证码")
        private String code;

    }

    @ApiModel("验证信息")
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    private static class AccessUsersVO {
        @ApiModelProperty(position = 10, value = "token")
        private AccessTokenVO token;
        @ApiModelProperty(position = 20, value = "用户信息")
        private UsersVO users;
    }

    @Autowired
    @Lazy
    private UsersServiceImpl usersService;
    @Autowired
    @Lazy
    private UserDetailsServiceImpl userDetailsService;
    @Autowired
    private UserFriendsService tzUserFriendsService;
    @Resource(name = "wxMpService")
    private WxMpService wxMpService;
    @Resource(name = "wxAppService")
    private WxMpService wxAppService;
    @Resource(name = "wxAppPostgraduateService")
    private WxMpService wxAppPostgraduateService;
    @Autowired
    private UserFansService tzUserFansService;
    @Autowired
    private TargetServiceImpl targetService;
    @Autowired
    private ClientConfig clientConfig;
    @Autowired
    private LogServiceImpl logService;
    @Autowired
    private UserDiaryService userDiaryService;
    @Autowired
    private UsersStudyServiceImpl usersStudyService;
    @Autowired
    private LiveVideoService liveVideoService;
    @Autowired
    private UserRecommendServiceImpl userRecommendService;
    @Autowired
    private VipUserServiceImpl vipUserService;
    @Autowired
    Version version;
    @Resource(name = "gyfTaskExecutor")
    AsyncTaskExecutor gyfTaskExecutor;

}
